home *** CD-ROM | disk | FTP | other *** search
- package resize_fat::fat;
-
-
-
-
- use resize_fat::any;
- use resize_fat::io;
- use resize_fat::c_rewritten;
-
- 1;
-
- sub read($) {
- my ($fs) = @_;
-
- resize_fat::c_rewritten::read_fat(fileno $fs->{fd}, $fs->{fat_offset}, $fs->{fat_size}, $fs->{media});
-
- @{$fs->{clusters}{count}}{qw(free bad used)} =
- resize_fat::c_rewritten::scan_fat($fs->{nb_clusters}, $fs->{fs_type_size});
- }
-
- sub write($) {
- my ($fs) = @_;
-
- sysseek $fs->{fd}, $fs->{fat_offset}, 0 or die "write_fat: seek failed";
- foreach (1..$fs->{nb_fats}) {
- resize_fat::c_rewritten::write_fat(fileno $fs->{fd}, $fs->{fat_size});
- }
- }
-
-
-
-
-
-
-
- sub allocate_remap {
- my ($fs, $cut_point) = @_;
- my ($cluster, $new_cluster);
- my $remap = sub { resize_fat::c_rewritten::set_fat_remap($cluster, $new_cluster) };
- my $get_new = sub {
- $new_cluster = get_free($fs);
- 0 < $new_cluster && $new_cluster < $cut_point or die "no free clusters";
- set_eof($fs, $new_cluster);
-
- };
-
- resize_fat::c_rewritten::allocate_fat_remap($fs->{fat_size});
-
- $fs->{last_free_cluster} = 2;
- for ($cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
- if ($cluster < $cut_point) {
- if (resize_fat::c_rewritten::flag($cluster) == $resize_fat::any::DIRECTORY) {
- &$get_new();
- } else {
- $new_cluster = $cluster;
- }
- &$remap();
- } elsif (!is_empty(&next($fs, $cluster))) {
- &$get_new();
- &$remap();
- }
- }
- }
-
-
-
- sub update {
- my ($fs) = @_;
-
- for (my $cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
- if (resize_fat::c_rewritten::flag($cluster)) {
- my $old_next = &next($fs, $cluster);
- my $new = resize_fat::c_rewritten::fat_remap($cluster);
- my $new_next = resize_fat::c_rewritten::fat_remap($old_next);
-
- set_available($fs, $cluster);
-
- is_eof($old_next) ?
- set_eof($fs, $new) :
- set_next ($fs, $new, $new_next);
- }
- }
- }
-
-
- sub endianness16($) { (($_[0] & 0xff) << 8) + ($_[0] >> 8); }
- sub endianness($$) {
- my ($val, $nb_bits) = @_;
- my $r = 0;
- for (; $nb_bits > 0; $nb_bits -= 8) {
- $r <<= 8;
- $r += $val & 0xff;
- $val >>= 8;
- }
- $nb_bits < 0 and die "error: endianness only handle numbers divisible by 8";
- $r;
- }
-
- *next = \&resize_fat::c_rewritten::next;
- *set_next = \&resize_fat::c_rewritten::set_next;
-
-
-
- sub get_free($) {
- my ($fs) = @_;
- foreach (my $i = 0; $i < $fs->{nb_clusters}; $i++) {
- my $cluster = ($i + $fs->{last_free_cluster} - 2) % $fs->{nb_clusters} + 2;
- is_available(&next($fs, $cluster)) and return $fs->{last_free_cluster} = $cluster;
- }
- die "no free clusters";
- }
-
-
- sub is_eof($) {
- my ($cluster) = @_;
- $cluster >= $resize_fat::bad_cluster_value;
- }
- sub set_eof($$) {
- my ($fs, $cluster) = @_;
- set_next ($fs, $cluster, $resize_fat::bad_cluster_value + 1);
- }
-
-
- sub is_empty($) {
- my ($cluster) = @_;
- $cluster == 0 || $cluster == $resize_fat::bad_cluster_value;
- }
-
-
- sub is_available($) {
- my ($cluster) = @_;
- $cluster == 0;
- }
- sub set_available($$) {
- my ($fs, $cluster) = @_;
- set_next ($fs, $cluster, 0);
- }
-